﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ThiefRun.States;

namespace ThiefRun.Character
{
    public class Character
    {
        #region Constants
        // Constants
        #endregion Constants

        #region Properties
        // Properties
        public MovementProperties linear;
        public MovementProperties angular;
        protected int floor;

        protected Color colour;
        protected ThiefRunGame game;
        protected Texture2D texture;
        protected Vector2 size;
        protected LevelState state;
        #endregion Properties

        #region Computed Properties
        // Computed Properties
        // Determine the extent of the NPC.
        public Rectangle Bounds
        {
            get { return new Rectangle((int)linear.position.X, (int)linear.position.Y, (int)size.X, (int)size.Y); }
        }
        public bool OnCurrentFloor { get { return (floor == state.currentLevel.CurrentFloor); } }
        public int Floor { get { return floor; } set { floor = value; } }
        public Vector2 Middle { get { return new Vector2(linear.position.X + (size.X / 2F), linear.position.Y + (size.Y / 2F)); } }
        #endregion Computed Properties

        #region Methods
        // Methods

        public Character(ThiefRunGame game, LevelState state, Texture2D texture, Vector2 position, Vector2 size, Vector2 direction, Vector2 velocity, Color colour, int floor)
        {
            this.game = game;
            this.texture = texture;
            this.linear = new MovementProperties(position, velocity, Vector2.Zero);
            this.size = size;
            this.angular = new MovementProperties(direction, Vector2.Zero, Vector2.Zero);
            this.colour = colour;
            this.floor = floor;
            this.state = (LevelState)state;
        }

        // Draw the NPC.
        public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            Rectangle? sourceRect = Bounds;

            if (OnCurrentFloor)
            {
                spriteBatch.Begin();
                spriteBatch.Draw(texture, Bounds, colour);
                //spriteBatch.Draw(texture, Bounds, sourceRect, colour, angular.position.X, Middle, SpriteEffects.None, 1F);
                spriteBatch.End();
            }
        }

        // Prevent the character from escaping the level's bounds.
        protected virtual void CheckBounds()
        {
            // The stage is a level stage.
            if (state is LevelState)
            {
                LevelState levelStage = (LevelState)state;

                // Prevent the character from going off screen by the left edge.
                if (linear.position.X < levelStage.currentLevel.Bounds.Left + (size.X / 2))
                {
                    linear.position.X = levelStage.currentLevel.Bounds.Left + (size.X / 2);
                }

                // Prevent the character from going off screen by the right edge.
                if ((linear.position.X) > levelStage.currentLevel.Bounds.Right - (size.X / 2))
                {
                    linear.position.X = levelStage.currentLevel.Bounds.Right - (size.X / 2);
                }

                // Prevent the character from going off screen by the top edge.
                if (linear.position.Y < levelStage.currentLevel.Bounds.Top + 25)
                {
                    linear.position.Y = levelStage.currentLevel.Bounds.Top + 25;
                }

                // Prevent the character from going off screen by the bottom edge.
                if ((linear.position.Y) > levelStage.currentLevel.Bounds.Bottom - (size.Y / 5))
                {
                    linear.position.Y = levelStage.currentLevel.Bounds.Bottom - (size.Y / 5);
                }
            }
        }


        public virtual bool CheckCollision(Character other)
        {
            if (Bounds.Intersects(other.Bounds))
                return true;
            else
                return false;
        }

        // Check if two characters are colliding.
        public virtual bool Collides(Character other)
        {
            // The character is on the current level.
            return ((OnCurrentFloor) && (other.OnCurrentFloor) && (Bounds.Intersects(other.Bounds)));
        }
        #endregion Methods
    }
}
